package com.roc.template.activiti.util;

import com.roc.template.activiti.nodeDto.Line;
import com.roc.template.activiti.nodeDto.Node;
import com.roc.template.activiti.nodeDto.ProcessJson;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.*;
import org.activiti.bpmn.model.Process;
import org.activiti.validation.ProcessValidator;
import org.activiti.validation.ProcessValidatorFactory;
import org.activiti.validation.ValidationError;

import java.util.List;
import java.util.Map;

/**
 * @ClassName ProcessUtils
 * @Description: TODO
 * @Author Administrator
 * @Date 2020/8/18 13 24
 * @Version V1.0
 **/
public class ProcessUtils {

    public static void main(String[] args) {
        ProcessValidatorFactory processValidatorFactory = new ProcessValidatorFactory();
        ProcessValidator processValidator = processValidatorFactory.createDefaultProcessValidator();
        ProcessJson processJson = new ProcessJson();
        BpmnModel bpmnModel = genarateBpmnModel(processJson);
        List<ValidationError> validate = processValidator.validate(bpmnModel);
        if(validate.size()>=1){
            for (ValidationError validationError : validate) {
                System.out.println(validationError.getProblem());
                System.out.println(validationError.isWarning());
            }
        }
        BpmnXMLConverter bpmnXMLConverter = new BpmnXMLConverter();

        byte[] bytes = bpmnXMLConverter.convertToXML(bpmnModel);
        System.out.println(new String(bytes));
    }

    public static BpmnModel genarateBpmnModel(ProcessJson processJson){
        //创建BpmnModel对象
        BpmnModel bpmnModel = new BpmnModel();

        Process process = new Process();
        //executabl内置默认为true

        Map<String, Object> attr = processJson.getAttr();
        process.setId(attr.get("id").toString());
        process.setName("My process");

        List<Node> nodes = processJson.getNodes();
        for(Node node:nodes) {
            //起始节点
            if(node.getId().startsWith("start")) {
                StartEvent startEvent = new StartEvent();
                startEvent.setId(node.getId());
                startEvent.setName(node.getName());
                process.addFlowElement(startEvent);
                continue;
            }

            //结束节点
            if(node.getId().startsWith("end")) {
                EndEvent endEvent = new EndEvent();
                endEvent.setId(node.getId());
                endEvent.setName(node.getName());
                process.addFlowElement(endEvent);
                continue;
            }

            //用户节点
            UserTask apply = genarateUserTask(node.getId(),node.getName());
            process.addFlowElement(apply);
        }

        List<Line> lines = processJson.getLines();
        for(Line line: lines) {
            List<Map<String, Object>> compares = line.getCompares();
            StringBuffer stringBuffer = new StringBuffer();
            if(compares!=null && compares.size()!=0) {
                stringBuffer.append("${");
                for(Map<String, Object> map : compares) {
                    String fieldName = map.get("fieldName").toString();
                    String operation = map.get("operation").toString();
                    String value = map.get("value").toString();
                    stringBuffer.append(fieldName+operation+value);
                }
                stringBuffer.append("}");
            }
            SequenceFlow sequenceFlow1 = genarateSequenceFlow(line.getId(),"",line.getFrom(),line.getTo(),stringBuffer.toString(),process);
            process.addFlowElement(sequenceFlow1);
        }

        /**
         * 创建连线 并添加至process
         * <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
         */
//        SequenceFlow sequenceFlow1 = genarateSequenceFlow("flow1","","startevent1","apply","",process);
//        SequenceFlow sequenceFlow2 = genarateSequenceFlow("flow2","","apply","leader","",process);
//        SequenceFlow sequenceFlow3 = genarateSequenceFlow("flow3","","leader","hr","${day <= 3}",process);
//        SequenceFlow sequenceFlow4 = genarateSequenceFlow("flow4","","leader","manage","${day > 3}",process);
//        SequenceFlow sequenceFlow5 = genarateSequenceFlow("flow5","","manage","hr","",process);
//        SequenceFlow sequenceFlow6 = genarateSequenceFlow("flow6","","hr","endevent2","",process);
//        process.addFlowElement(sequenceFlow1);
//        process.addFlowElement(sequenceFlow2);
//        process.addFlowElement(sequenceFlow3);
//        process.addFlowElement(sequenceFlow4);
//        process.addFlowElement(sequenceFlow5);
//        process.addFlowElement(sequenceFlow6);


        /**
         * 将process封装至模型对象
         */
        bpmnModel.addProcess(process);

        return bpmnModel;

    }

    /**
     * 创建连线
     */
    private static SequenceFlow genarateSequenceFlow(String id, String name,String sourceRef, String tartgetRef, String conditionExpression, Process process) {
        SequenceFlow sequenceFlow = new SequenceFlow(sourceRef,tartgetRef);
        sequenceFlow.setId(id);
        if(name != null && name != ""){
            sequenceFlow.setName(name);
        }
        sequenceFlow.setSourceFlowElement(process.getFlowElement(sourceRef));
        sequenceFlow.setTargetFlowElement(process.getFlowElement(tartgetRef));
        if(conditionExpression !=null && conditionExpression != ""){
            sequenceFlow.setConditionExpression(conditionExpression);
        }
        return sequenceFlow;
    }

    /**
     * 创建排他网关
     */
    private static ExclusiveGateway genarateExclusiveGateway(String id, String name) {
        ExclusiveGateway exclusiveGateway = new ExclusiveGateway();
        exclusiveGateway.setId(id);
        exclusiveGateway.setName(name);
        return exclusiveGateway;
    }

    /**
     * 创建用户人物节点
     */
    private static UserTask genarateUserTask(String id, String name) {
        UserTask userTask = new UserTask();
        userTask.setId(id);
        userTask.setName(name);
//        userTask.setAssignee("${"+name+"}");
        return userTask;
    }

}
